package org.yuezejian.alarm.netty.channel;

import org.yuezejian.alarm.netty.enums.ClientType;
import org.yuezejian.alarm.netty.handler.AbstractClientHandler;
import org.yuezejian.alarm.netty.handler.ClientHandlerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 自定义Websocket ChannelInitializer
 *
 * @author yuezejian
 * @since 2024.8.1
 */
@Slf4j
@Component
public class WebsocketCustomChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Autowired
    private ClientHandlerFactory clientHandlerFactory;

    private ClientType clientType; // 协议类型
    private String handlerType; // 处理器类型

    // 设置协议类型和处理器类型的方法
    public void setClientType(ClientType clientType) {
        this.clientType = clientType; // 设置协议类型
    }

    public void setHandlerType(String handlerType) {
        this.handlerType = handlerType; // 设置处理器类型
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        if (handlerType == null) {
            throw new IllegalArgumentException("Protocol type and handler type cannot be null");
        }

        ChannelPipeline pipeline = ch.pipeline();

        // 添加 WebSocket 相关的处理器
        ByteBuf delimiter = Unpooled.copiedBuffer("@@".getBytes("UTF-8"));
        //使用@@作为SOCKET间隔符
        pipeline.addLast("framer",new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, delimiter));
        //目前只支持String编码
        pipeline.addLast("encoder", new StringEncoder());
        //应答数据需使用String解码
        pipeline.addLast("decoder", new StringDecoder());

        // 使用工厂创建相应的 ClientHandler
        AbstractClientHandler handler = clientHandlerFactory.createHandler(handlerType);
        if (handler != null) {
            pipeline.addLast(handler); // 将处理器添加到管道中
        } else {
            throw new IllegalStateException("Failed to create handler for type: " + handlerType);
        }
    }
}
